<?php

namespace addons\TfFutures\common\models;

use addons\TfFutures\common\models\Symbol as SymbolXh;
use common\helpers\ResultDataHelper;
use common\models\member\Member as Member2;
use yii\db\ActiveRecord;
use Yii;
use trade\common\service\KlineService;

/**
 * 用户应用信息表.
 */
class Order extends ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return '{{%addon_tf_futures_order}}';
    }

    public function rules()
    {
        return [
            [['id', 'member_id', 'volume','lever_id'], 'integer'],
            [['rise_fall', 'close_type','order_number'], 'string'],
            [
                [
                    'contract_size',
                    'service_fee',
                    'overfee',
                    'deposit',
                    'profit',
                    'open_price',
                    'close_price',
                    'stop_profit_price',
                    'stop_profit_point',
                    'stop_loss_price',
                    'stop_loss_point',
                ],
                'number',
            ],
            [['open_time', 'close_time', 'expiration'], 'safe'],
            [['symbol'], 'string', 'max' => 50],
            [['symbol_cn', 'desc'], 'string', 'max' => 255],
            [['id'], 'unique'],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id'                => 'ID',
            'member_id'         => '用户ID',
            'symbol'            => '产品代码',
            'symbol_cn'         => '产品名称',
            'contract_size'     => '合约量',
            'rise_fall'         => '买卖类型',
            'volume'            => '手数',
            'service_fee'       => '手续费',
            'overfee'           => '过夜费/延保费',
            'deposit'           => '保证金',
            //'lever_id'          => '杠杆id',
            'profit'            => '盈亏',
            'open_price'        => '开仓价',
            'open_time'         => '开仓时间',
            'close_price'       => '平仓价',
            'close_type'        => '平仓类型',
            'close_time'        => '平仓时间',
            'stop_profit_price' => '止盈金额',
            'stop_profit_point' => '止盈点数',
            'stop_loss_price'   => '止损金额',
            'stop_loss_point'   => '止损点数',
            'expiration'        => '自动平仓时间',
            'desc'              => '描述/备注',
            'state'             => '订单状态',
            'status'            => '状态',
            'created_at'         => '创建时间',
            'updated_at'         => '修改时间',
        ];
    }

    public function getMember_info()
    {
        return $this->hasOne(Member2::class, ['id' => 'member_id']);
    }



    /**
     * 判断一个品类当前是否处于交易时间内
     *
     * @param  string      $tradestr 时间段：13:00-14:00;00:00-10:00
     * @param  int        $early     提前时间量，单位秒
     * @return boolean
     */
    public static function isTradeTime($tradestr='', $weekend=true,$early = 300)
    {

        if( !$weekend && in_array(date('w'),['0','6']) ){
            return false;
        }

        $times    = [];
        $tradestr = explode(';',$tradestr);
        foreach ($tradestr as $trade){
            $trade = explode(explode('-',$trade));
            if( count($trade)==2 && strlen($trade[0])==5 && strlen($trade[1])==5 ){
                $times[] = ['start'=>$trade[0],'end'=>$trade[1]];
            }
        }

        if ( !empty($times) )
        {
            $now = time();
            foreach ($times as $item)
            {
                $start = strtotime(date('Y-m-d ' . $item['start'] . ':00'));
                $end   = strtotime(date('Y-m-d ' . $item['end']   . ':00'));
                if ($start > $end)
                {
                    if ($now > $start && $now < $start + 3600 * 24 || $now < $end - $early) {
                        return true;
                    }
                } else {
                    if ($now > $start && $now < $end - $early) {
                        return true;
                    }
                }
            }
            return false;
        }
        return true;
    }

    /**
     * 验证价格
     * @param $product             产品 || 产品id
     * @param $productcmd          买卖类型
     * @param $rise_fall           买卖方向
     * @param $price               验证价格
     * @param $stop_profit_price   止盈价格
     * @param $stop_loss_price     止损价格
     * @return mixed
     * @throws \Exception
     *                             **/
    public static function checkPriceWithPrice($product, $productcmd, $rise_fall, $price, $stop_profit_price = 0, $stop_loss_price = 0)
    {
        if (is_numeric($product)) {
            $product = SymbolXh::find()->where(['code2'=>$product])->one();
        }
        if (empty($product)) {
            throw new \Exception('产品不存在');
        }
        if (!in_array(strtoupper($productcmd),
                ['NOW', 'GT', 'LT']) || !in_array(strtoupper($rise_fall), ['RISE', 'FALL'])) {
            throw new \Exception('买卖方向错误');
        }
        //获取最新价格
        $newPrice                  = new KlineService();
        $newPrice                  = $newPrice->loadTicekt($product['code'],'tf_futures_trade');
        // Yii::$app->services->kline->prex = 'rf_addon_tf_futures_symbol';
        // $newPrice = Yii::$app->services->kline->loadTicekt($product['code']);
        if (empty($newPrice['price'])) {
            throw new \Exception('最新价格获取失败');
        }
        $product_price = $newPrice['price'];
        //用户挂单
        if ($productcmd == 'GT' && $price <= $product_price) {
            throw new \Exception('挂单价格不能低于' . $product_price);
        }else if ($productcmd == 'LT' && $price >= $product_price) {
            throw new \Exception('挂单价格不能高于' . $product_price);
        }

        $unit_price = bcdiv($product->unit_price, $product->unit, 4);
        if ($rise_fall == 'RISE') {
            $maxrise = $product->maxrise > 0
                ? bcadd($price, bcmul($product->maxrise, $unit_price, 4), 4)
                : 0;
            $minrise = $product->minrise > 0
                ? bcadd($price, bcmul($product->minrise, $unit_price, 4), 4)
                : 0;
            $maxlost = $product->maxlost > 0
                ? bcsub($price, bcmul($product->maxlost, $unit_price, 4), 4)
                : 0;
            $minlost = $product->minlost > 0
                ? bcsub($price, bcmul($product->minlost, $unit_price, 4), 4)
                : 0;
            if ($stop_profit_price > 0) {
                if ($maxrise > 0 && $stop_profit_price > $maxrise) {
                    throw new \Exception('止盈价格不能高于' . $maxrise);
                }
                if ($minrise > 0 && $stop_profit_price < $minrise) {
                    throw new \Exception('止盈价格不能低于' . $minrise);
                }
            }
            if ($stop_loss_price > 0) {
                if ($maxlost > 0 && $stop_loss_price < $maxlost) {
                    throw new \Exception('止损价格不能低于' . $maxlost);
                }
                if ($minlost > 0 && $stop_loss_price > $minlost) {
                    throw new \Exception('止损价格不能高于' . $minlost);
                }
            }
        }elseif ($rise_fall == 'FALL') {
            $maxrise = $product->maxrise > 0
                ? bcsub($price, bcmul($product->maxrise, $unit_price, 4), 4)
                : 0;
            $minrise = $product->minrise > 0
                ? bcsub($price, bcmul($product->minrise, $unit_price, 4), 4)
                : 0;
            $maxlost = $product->maxlost > 0
                ? bcadd($price, bcmul($product->maxlost, $unit_price, 4), 4)
                : 0;
            $minlost = $product->minlost > 0
                ? bcadd($price, bcmul($product->minlost, $unit_price, 4), 4)
                : 0;
            if ($stop_profit_price > 0) {
                if ($maxrise > 0 && $stop_profit_price < $maxrise) {
                    throw new \Exception('止盈价格不能低于' . $maxrise);
                }
                if ($minrise > 0 && $stop_profit_price > $minrise) {
                    throw new \Exception('止盈价格不能高于' . $minrise);
                }
            }
            if ($stop_loss_price > 0) {
                if ($maxlost > 0 && $stop_loss_price > $maxlost) {
                    throw new \Exception('止损价格不能高于' . $maxlost);
                }
                if ($minlost > 0 && $stop_loss_price < $minlost) {
                    throw new \Exception('止损价格不能低于' . $minlost);
                }
            }
        }

        return ['code' => 200, 'msg' => 'ok'];
    }

    /**
     * 盈亏计算
     * @param      $product     产品id
     * @param      $order       订单id
     * @param null $close_price 平仓价格
     * @return mixed
     */
    public static function computeProfit($symbol, $order, $close_price = NULL)
    {

        if (empty($symbol)) {
            throw new \Exception('缺少产品订单');
        }
        $product = Symbol::find()->where(['code'=>$symbol])->one();
        if (empty($product)) {
            throw new \Exception('产品不存在');
        }
        if (is_numeric($order)) {
            $order = Order::find()
                          ->where(['id' => $order])
                          ->one();
        }
        if (empty($order)) {
            $order = OrderReason::find()
                                ->where(['id' => $order])
                                ->one();
        }
        if (empty($order)) {
            throw new \Exception('订单不存在');
        }
        //没有给现价
        if (empty($close_prise) || !is_numeric($close_prise) ) {

            //获取平仓价格
            $close_prise_obj  = new KlineService();
        	$close_prise_obj  = $close_prise_obj->loadTicekt($product['code'],'tf_futures_trade');
			// Yii::$app->services->kline->prex = 'rf_addon_tf_futures_symbol';
   //     	$close_prise_obj = Yii::$app->services->kline->loadTicekt($product['code']);
            //现价
            $close_price = $close_prise_obj['price'];
        }
        //每1点的价格
        $unit_price = bcdiv($product->unit_price, $product->unit, 8);
        //买涨
        if ($order->rise_fall == 'RISE') {
            //最大止盈 (最多挣多少)
            $maxRise = $product->maxrise > 0 ? bcadd($order->open_price, bcmul($product->maxrise, $unit_price, 4), 4) : 0;
            //最大止损 (最多亏多少)
            $maxLost = $product->maxlost > 0 ? bcsub($order->open_price, bcmul($product->maxlost, $unit_price, 4), 4) : 0;

            if ($maxRise > 0 && $close_price > $maxRise) {
                $close_price = $maxRise;
            }
            if ($maxLost > 0 && $close_price < $maxLost) {
                $close_price = $maxLost;
            }
            //平仓价 - 开仓价
            $diffPrice = bcsub($close_price, $order->open_price, 6);
        }else if ($order->rise_fall == 'FALL') {

            //最大止盈 (最多挣多少)
            $maxRise = $product->maxrise > 0
                ? bcsub($order->open_price, bcmul($product->maxrise, $unit_price, 4), 4)
                : 0;
            //最大止损 (最多亏多少)
            $maxLost = $product->maxlost > 0
                ? bcadd($order->open_price, bcmul($product->maxlost, $unit_price, 4), 4)
                : 0;
            if ($maxRise > 0 && $close_price < $maxRise) {
                $close_price = $maxRise;
            }
            if ($maxLost > 0 && $close_price > $maxLost) {
                $close_price = $maxLost;
            }
            //平仓价 - 开仓价
            $diffPrice = bcsub($order->open_price,$close_price , 6);
        }else {
            throw new \Exception('买卖方向错误');
        }
        return [
            $close_price,
            bcmul($product->contract_size,
                bcmul(bcmul($diffPrice, $unit_price, 4), $order->volume, 4), 4),
        ];
    }
}
